<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram of Fish in a Tank</title>
</head>
<body>
<canvas id="physicsCanvas" width="700" height="400"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // --- Style and Configuration ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // --- Parameters ---
    const cx = 330;
    const cy = 200;
    const R = 150;
    const tankHalfHeight = 80;
    const curveStartOffset = 25;

    // --- Helper Functions ---

    /**
     * Draws an arrow from a starting point to an end point.
     * @param {CanvasRenderingContext2D} ctx - The rendering context.
     * @param {number} fromx - The x-coordinate of the starting point.
     * @param {number} fromy - The y-coordinate of the starting point.
     * @param {number} tox - The x-coordinate of the end point (arrow tip).
     * @param {number} toy - The y-coordinate of the end point (arrow tip).
     * @param {number} headlen - The length of the arrowhead lines.
     */
    function drawArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
        const angle = Math.atan2(toy - fromy, tox - fromx);
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        // Draw the two lines of the arrowhead
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }
    
    /**
     * Draws an arrowhead at a specific point with a given orientation.
     * @param {CanvasRenderingContext2D} ctx - The rendering context.
     * @param {number} tipX - The x-coordinate of the arrowhead tip.
     * @param {number} tipY - The y-coordinate of the arrowhead tip.
     * @param {number} angle - The angle (in radians) of the arrow's direction.
     * @param {number} headlen - The length of the arrowhead lines.
     */
    function drawArrowHead(ctx, tipX, tipY, angle, headlen = 10) {
        ctx.beginPath();
        ctx.moveTo(tipX, tipY);
        ctx.lineTo(tipX - headlen * Math.cos(angle - Math.PI / 6), tipY - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tipX, tipY);
        ctx.lineTo(tipX - headlen * Math.cos(angle + Math.PI / 6), tipY - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }


    // --- Drawing Start ---

    // 1. Draw the Fish Tank
    const xLeftStraight = cx - R + curveStartOffset;
    const xRightStraight = cx + R - curveStartOffset;
    const yTop = cy - tankHalfHeight;
    const yBottom = cy + tankHalfHeight;
    const xLeftExtreme = cx - R;
    const xRightExtreme = cx + R;

    ctx.beginPath();
    ctx.moveTo(xLeftStraight, yTop);
    ctx.lineTo(xRightStraight, yTop);
    ctx.quadraticCurveTo(xRightExtreme, cy, xRightStraight, yBottom);
    ctx.lineTo(xLeftStraight, yBottom);
    ctx.quadraticCurveTo(xLeftExtreme, cy, xLeftStraight, yTop);
    ctx.stroke();

    // 2. Draw '2R' Dimension Line
    const dimY = yTop - 40;
    
    // Vertical extension lines
    ctx.beginPath();
    ctx.moveTo(xLeftExtreme, yTop);
    ctx.lineTo(xLeftExtreme, dimY);
    ctx.moveTo(xRightExtreme, yTop);
    ctx.lineTo(xRightExtreme, dimY);
    ctx.stroke();
    
    // Horizontal line with arrowheads
    ctx.beginPath();
    ctx.moveTo(xLeftExtreme, dimY);
    ctx.lineTo(xRightExtreme, dimY);
    ctx.stroke();
    drawArrowHead(ctx, xLeftExtreme, dimY, 0);       // Head at left end, pointing right
    drawArrowHead(ctx, xRightExtreme, dimY, Math.PI); // Head at right end, pointing left
    
    // Label for 2R
    ctx.font = '24px Times New Roman';
    ctx.fillText('2R', cx, dimY - 20);

    // 3. Draw Center Point
    ctx.beginPath();
    ctx.arc(cx, cy, 3, 0, 2 * Math.PI);
    ctx.fill();

    // 4. Draw Fish and its Velocity
    ctx.font = '24px sans-serif';
    ctx.fillText('鱼', xLeftExtreme - 25, cy);
    ctx.beginPath();
    ctx.arc(xLeftExtreme, cy, 3, 0, 2 * Math.PI);
    ctx.fill();
    
    // Velocity Arrow
    drawArrow(ctx, xLeftExtreme + 10, cy, cx - 60, cy);
    
    // Velocity Label (v with subscript 鱼)
    ctx.font = 'italic 20px Times New Roman';
    ctx.fillText('v', cx - 110, cy - 15);
    ctx.save();
    ctx.font = '14px sans-serif'; // smaller font for subscript
    ctx.textAlign = 'left';
    // The label `v_fis` is shown in the image, where "fis" is a stylized representation of "鱼" (fish)
    ctx.fillText('fii', cx - 100, cy - 12);
    ctx.restore();


    // 5. Draw Radius 'R'
    drawArrow(ctx, cx, cy, xRightExtreme, cy);
    ctx.font = 'italic 24px Times New Roman';
    ctx.fillText('R', cx + R / 2, cy - 20);

    // 6. Draw Observer Axis and Label
    ctx.save();
    ctx.beginPath();
    ctx.setLineDash([5, 5]);
    ctx.moveTo(cx, cy);
    ctx.lineTo(xRightExtreme + 100, cy);
    ctx.stroke();
    ctx.restore();
    
    // Observer symbol and text
    ctx.font = '24px sans-serif';
    ctx.fillText('*', xRightExtreme + 50, cy);
    ctx.fillText('观察者', xRightExtreme + 50, cy + 30);

</script>
</body>
</html>